#include "stdafx.h"
#include "sql_order_box.h"

using namespace ui;

namespace ui_comp
{
	SqlOrderBox::SqlOrderBox() :ListBox(new ui::VLayout()) {
		SetAutoDestroyChild(false);
	};
	SqlOrderBox::~SqlOrderBox() {
		if (m_pMenuField) {
			m_pMenuField->Close();
			m_pMenuField = nullptr;
		}
			
		for (SqlOrderElement* ele : m_vecOrderElement)
			delete ele;
		for (SqlOrderElement* ele : m_vecOrderElementCache)
			delete ele;
		m_vecOrderElement.clear();
		m_vecOrderElementCache.clear();
	}

	void SqlOrderBox::Init() {
		__super::Init();
		ListContainerElement* ele = new ListContainerElement;
		GlobalManager::FillBoxWithCache(ele, L"ui_kit/sql_kit/filter_element_add.xml");
		Button* btnAdd = (Button*)ele->FindSubControl(L"add");
		btnAdd->AttachClick(nbase::Bind(&SqlOrderBox::OnListItemAddClicked, this, std::placeholders::_1));
		Add(ele);
	}

	bool SqlOrderBox::InsertOrderItemInfo(const std::string& field, const std::string& order, int index/* = -1*/) {
		assert(order == "desc" || order == "asc");
		SqlOrderItemInfoPtr info = std::make_shared<ui_comp::SqlOrderItemInfo>(field, order, true);
		return InsertOrderItemInfo(info, index);
	}

	bool SqlOrderBox::InsertOrderItemInfo(SqlOrderItemInfoPtr info, int index/* = -1*/) {
		if (!info)
			return false;
		SqlOrderElement* ele = nullptr;
		if (m_vecOrderElementCache.empty())
			ele = CreateOrderElement(L"ui_kit/sql_kit/order_element.xml");
		else {
			ele = m_vecOrderElementCache.front();
			m_vecOrderElementCache.erase(m_vecOrderElementCache.begin());
		}
		if (!ele)
			return false;
		ele->SetFieldKvList(m_pFieldKvList);
		ele->SetOrderItemInfo(info->field, info->order, info->selected);

		int itemIndex = index;
		if (index < 0 || index >= m_vecOrderElement.size()) {
			itemIndex = m_vecOrderElement.size();
			m_vecOrderElement.push_back(ele);
		}
		else
			m_vecOrderElement.insert(m_vecOrderElement.begin() + index, ele);
		return AddAt(ele, itemIndex);
	}

	bool SqlOrderBox::RemoveOrderElement(SqlOrderElement* ele) {
		if (!ele)
			return false;
		auto it = std::find(m_vecOrderElement.begin(), m_vecOrderElement.end(), ele);
		assert(it != m_vecOrderElement.end());
		if (it == m_vecOrderElement.end())
			return false;
		m_vecOrderElement.erase(it);
		Remove(ele);
		assert(GetCount() > 0);
		ele->Clear();
		m_vecOrderElementCache.push_back(ele);
		return true;
	}
	bool SqlOrderBox::RemoveAllOrderElement() {
		for (SqlOrderElement* ele : m_vecOrderElement) {
			ele->Clear();
			Remove(ele);
		}
		assert(GetCount() == 1);
		m_vecOrderElementCache.insert(m_vecOrderElementCache.end(), m_vecOrderElement.begin(), m_vecOrderElement.end());
		m_vecOrderElement.clear();
		return true;
	}

	SqlOrderElement* SqlOrderBox::CreateOrderElement(std::wstring sXml) {
		SqlOrderElement* ele = new SqlOrderElement();
		GlobalManager::FillBoxWithCache(ele, sXml);
		return ele;
	}

	std::vector<SqlOrderItemInfoPtr> SqlOrderBox::MakeOrderItemInfoList(bool isCheckSelected) {
		std::vector<SqlOrderItemInfoPtr> vecInfo;
		for (SqlOrderElement* ele : m_vecOrderElement)
		{
			if (isCheckSelected && !ele->IsElementSelected())
				continue;

			std::string field = ele->GetField();
			std::string order = ele->GetOrder();
			assert((order == "desc" || order == "asc"));
			SqlOrderItemInfoPtr info = std::make_shared<SqlOrderItemInfo>();
			info->field = field;
			info->order = order;
			info->selected = ele->IsElementSelected();
			vecInfo.push_back(info);
		}
		return vecInfo;
	}

	void SqlOrderBox::SetFieldKvList(const std::vector<ui::kvItem>& vecFieldKv) {
		if (!m_pFieldKvList)
			m_pFieldKvList = std::make_shared<ui::UiKvList>();
		*m_pFieldKvList = vecFieldKv;
		for (SqlOrderElement* ele : m_vecOrderElement)
		{
			ele->SetFieldKvList(m_pFieldKvList);
		}
	}

	bool SqlOrderBox::OnMenuFieldItem(ui::EventArgs* args, std::wstring sField)
	{
		if (!m_pListItemOfMenuField)
			return true;
		m_pListItemOfMenuField->SetField(nbase::UTF16ToUTF8(sField));
		return true;
	}

	bool SqlOrderBox::OnListItemAddClicked(ui::EventArgs* args)
	{
		InsertOrderItemInfo("");
		return true;
	}
}






